package edu.hit.stu.config;

import com.fasterxml.classmate.TypeResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.ResponseEntity;
import org.springframework.web.context.request.async.DeferredResult;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.AlternateTypeRules;
import springfox.documentation.schema.ScalarType;
import springfox.documentation.schema.WildcardType;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger.web.*;

import java.util.ArrayList;
import java.util.List;

import static java.util.Collections.newSetFromMap;
import static java.util.Collections.singletonList;

@Configuration
public class SwaggerConfig {

    ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("用户信息")
                .description("处理 `用户信息` 的CRUD接口")
                .license("Apache 2.0")
                .licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html")
                .termsOfServiceUrl("http://www.baidu.com")
                .version("1.0.0")
                .contact(new Contact("刘智彬", "http://www.baidu.com", "979132073@qq.com"))
                .build();
    }

    @Bean
    public Docket userApi() {
        return new Docket(DocumentationType.OAS_30)
                .groupName("数据处理")
                .select()
                .apis(RequestHandlerSelectors.basePackage("edu.hit.stu.controller.api"))
                .build()
                .pathMapping("/")
//                .directModelSubstitute(LocalDate.class, String.class)
//                .servers(new Server("lzb_desktop", "https://{ip}:{port}/{basePath}", "本地笔记本", getServiceVariables(), null))
                .genericModelSubstitutes(ResponseEntity.class)
                .alternateTypeRules(
                        AlternateTypeRules.newRule(typeResolver.resolve(DeferredResult.class,
                                typeResolver.resolve(ResponseEntity.class, WildcardType.class)),
                                typeResolver.resolve(WildcardType.class)))
                .useDefaultResponseMessages(false)
                .securitySchemes(singletonList(apiKey()))
                .securityContexts(singletonList(securityContext()))
                .enableUrlTemplating(true)
                .globalRequestParameters(
                        singletonList(new springfox.documentation.builders.RequestParameterBuilder()
                                .name("X-Authentication")
                                .description("全局参数描述")
                                .in(ParameterType.HEADER)
                                .required(false)
                                .query(q -> q.model(m -> m.scalarModel(ScalarType.STRING)))
                                .build()))
                .apiInfo(apiInfo());
    }

    private List<ServerVariable> getServiceVariables() {
        ArrayList<ServerVariable> serverVariables = new ArrayList<>();
        serverVariables.add(new ServerVariable("ip", List.of("localhost", "127.0.0.1"), "localhost", "IP地址", null));
        serverVariables.add(new ServerVariable("port", List.of("80", "443"), "8080", "端口号", null));
        serverVariables.add(new ServerVariable("basePath", List.of("/api", "/mylib"), "", "基地址", null));
        return serverVariables;
    }

    @Autowired
    private TypeResolver typeResolver;

    private ApiKey apiKey() {
        return new ApiKey("X-Authentication", "JWT", "header");
    }

    private SecurityContext securityContext() {
        return SecurityContext.builder()
                .securityReferences(JWTAuth())
                .forPaths(PathSelectors.regex("/.*"))
                .build();
    }

    List<SecurityReference> JWTAuth() {
        AuthorizationScope authorizationScope
                = new AuthorizationScope("global", "全部资源");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        return singletonList(
                new SecurityReference("X-Authentication", authorizationScopes));
    }

    @Bean
    UiConfiguration uiConfig() {
        return UiConfigurationBuilder.builder()
                .deepLinking(true)
                .displayOperationId(true)
                .defaultModelsExpandDepth(1)
                .defaultModelExpandDepth(1)
                .defaultModelRendering(ModelRendering.EXAMPLE)
                .displayRequestDuration(true)
                .docExpansion(DocExpansion.LIST)
                .filter(true)
                .maxDisplayedTags(null)
                .operationsSorter(OperationsSorter.ALPHA)
                .showExtensions(true)
                .showCommonExtensions(true)
                .tagsSorter(TagsSorter.ALPHA)
                .supportedSubmitMethods(UiConfiguration.Constants.DEFAULT_SUBMIT_METHODS)
                .validatorUrl(null)
                .build();
    }

}
